⚕ 9 维向量知识图谱 · v1
L1-L9 · GRADE · Cochrane RoB 2 · MeSH Publication Types 2026 · PubMed 文献证据体
9-dim filled 100%
SAG 2026-07-28
--
疾病锚点
实体搜索
研究类型
全部
RCT
Meta-analysis / Systematic Review
Controlled Trial
Cohort
Case-Control
Cross-Sectional
Case Report
Observational
Narrative Review
Preprint
Unknown
证据等级
全部
High
Moderate
Low
Very Low
Excluded
应用
重置
包含临床前机制边 (kg_edges_mechanism)
91-疾病扩展路径 (ETL-A 2026-08-05)
反向因果路径 (L9→L1/L8/L5)
全部数据
PNG
JSON
★ Saved(
0
)
总边数
—
kg_edges rows
高质量 (high)
—
GRADE high
中等 (moderate)
—
GRADE moderate
冲突边
—
方向/极性矛盾
9 维字段填充率
全 11 字段
L1→L9 链路 Sankey
基于 chain_level 跨层流向
关系 × 证据等级 热图
relation × evidence_level
关系 × 极性 堆叠柱
+ / − / ~ / ?
研究类型分布
12 个 study_type 桶
因果强度分布
5 级:necessary / sufficient / contributory / correlational / co_occurs
高质量 Top 50 边
按 evidence_level + causal_strength + pmid_count 综合排序
证据等级
因果强度
研究类型
关系
极性
Source → Target
层级
PMID 数
PMID 溯源
Evidence
加载中...
扩展路径探索器 · 91 疾病覆盖 (ETL-A 2026-08-05)
加载中...
疾病
Chain Pair
L1 → L9
L8 → L9
L5 → L9
L6 → L9
L1 → L7
L9 → L7
跳数
全部
1
2
3
上限
20
50
100
200
查询
—
Path ID
疾病
Chain
层序列
节点数
关系数
PMID 数
PMID 预览
平均证据
选择疾病 + Chain Pair 后点击「查询」
🔄 反向因果路径
来源: ETL-B 2026-08-06 · disease_l1l9_paths_reverse
疾病
起止
L9→L1
L9→L8
L9→L5
L7→L1
L7→L5
L6→L1
L9→L7
L7→L2
L9→L2
L8→L1
L5→L1
hops
算法
全部
reverse_bfs (真新增)
reverse_flip (翻转)
cross_doc_join (异向拼接)
limit
查询反向路径
算法
链层级
hops
因果强度
证据等级
PMID列表
证据摘要
冲突说明
选择疾病后点击「查询反向路径」
方向矛盾边(kg_edges_conflict + 极性分裂)
Cochrane Handbook Ch.14 Inconsistency
conflict 表
极性分裂
类型
Source → Target
关系
极性集合
Evidence Level
Study Type
原因 / 说明
PMID 溯源
加载中...
Edge Detail
×
Loading...
★ Saved Paths
×
No saved paths yet
Click table row, then Save
// ===== A: 实体名搜索 ===== (function() { var debounceTimer = null; function initEntitySearch() { var inp = document.getElementById('entitySearchInput'); var dropdown = document.getElementById('entityDropdown'); var suggestList = document.getElementById('entitySuggestList'); if (!inp || !dropdown) return; inp.addEventListener('input', function() { clearTimeout(debounceTimer); var q = this.value.trim(); if (q.length < 2) { dropdown.classList.add('hidden'); return; } debounceTimer = setTimeout(async function() { try { var resp = await jget('/ai/api/kg/node_search?name=' + encodeURIComponent(q) + '&limit=8'); renderDropdown(resp.nodes || [], resp.query || q); } catch(e) { console.warn('entity search failed', e); } }, 300); }); inp.addEventListener('keydown', function(e) { if (e.key === 'Escape') { dropdown.classList.add('hidden'); return; } var items = dropdown.querySelectorAll('.entity-suggest-item'); if (!items.length) return; var active = dropdown.querySelector('.entity-suggest-item.active'); if (e.key === 'ArrowDown') { e.preventDefault(); if (active) active.classList.remove('active'); var nxt = active ? active.nextElementSibling : items[0]; if (nxt) nxt.classList.add('active'); } else if (e.key === 'ArrowUp') { e.preventDefault(); if (active) active.classList.remove('active'); var prv = active ? active.previousElementSibling : items[items.length - 1]; if (prv) prv.classList.add('active'); } else if (e.key === 'Enter') { var sel = dropdown.querySelector('.entity-suggest-item.active') || items[0]; if (sel) sel.click(); } }); document.addEventListener('click', function(e) { var wrap = document.getElementById('entitySearchWrap'); if (wrap && !wrap.contains(e.target)) dropdown.classList.add('hidden'); }); } window.initEntitySearch = initEntitySearch; function renderDropdown(nodes, query) { var dropdown = document.getElementById('entityDropdown'); var suggestList = document.getElementById('entitySuggestList'); if (!nodes || !nodes.length) { dropdown.innerHTML = '
No results
'; dropdown.classList.remove('hidden'); return; } dropdown.innerHTML = nodes.map(function(n) { var chainName = n.chain_name || 'L?'; var chainCss = (chainName === 'L8') ? ' l8' : (chainName === 'L9' ? ' l9' : ''); var orphan = n.is_orphan === 1 ? '
isolated
' : ''; var pmidCount = 0; try { var arr = (typeof n.pmids === 'string') ? JSON.parse(n.pmids) : (Array.isArray(n.pmids) ? n.pmids : []); pmidCount = arr.length; } catch(err) { pmidCount = 0; } var nameEsc = (n.name || '').replace(/'/g, "\'"); return '
' + '
' + chainName + '
' + '
' + escHtml(n.name || '') + '
' + '
(' + pmidCount + ' pmid)
' + orphan + '
'; }).join(''); dropdown.classList.remove('hidden'); if (suggestList) { suggestList.innerHTML = nodes.map(function(n) { return '
'; }).join(''); } } window._renderEntityDropdown = renderDropdown; window._selectEntityNode = function(name, nodeId) { var dropdown = document.getElementById('entityDropdown'); var inp = document.getElementById('entitySearchInput'); if (dropdown) dropdown.classList.add('hidden'); if (inp) inp.value = name; if (window.charts && window.charts.sankey) highlightSankeyNode(name); showToast('Highlighted: ' + name, 2000); }; function highlightSankeyNode(name) { try { var opt = charts.sankey.getOption(); if (!opt || !opt.series || !opt.series[0]) return; var nodes = opt.series[0].data; var found = false; for (var i = 0; i < nodes.length; i++) { if (nodes[i].name === name || nodes[i].id === name) { found = true; break; } } if (!found) { showToast('Not found in Sankey: ' + name, 2000); return; } charts.sankey.setOption({ series: [{ emphasis: { focus: 'adjacency', itemStyle: { borderColor: '#f59e0b', borderWidth: 2 } } }] }, false); showToast('Highlighted: ' + name, 2000); } catch(e) { console.warn('highlightSankeyNode error', e); } } })(); // ===== E: 边详情弹窗 ===== var _currentModalEdge = null; async function showEdgeDetail(source, target) { _currentModalEdge = { source: source, target: target }; var modal = document.getElementById('edgeDetailModal'); var body = document.getElementById('modalEdgeBody'); var title = document.getElementById('modalEdgeTitle'); if (!modal) return; modal.classList.remove('hidden'); title.textContent = source + ' -> ' + target; body.innerHTML = '
Loading...
'; try { var resp = await jget('/ai/api/kg/edge_detail?source=' + encodeURIComponent(source) + '&target=' + encodeURIComponent(target)); renderEdgeDetailModal(body, resp, source, target); } catch(e) { body.innerHTML = '
Load failed: ' + escHtml(e.message) + '
'; } } function renderEdgeDetailModal(body, resp, src, tgt) { var edges = resp.edges || []; if (!edges.length) { body.innerHTML = '
No edge data found
'; return; } var edge = edges[0]; var pmids = edge.pmids_list || []; var pmidLinks = pmids.length ? pmids.map(function(p) { return '
PMID:' + p + '
'; }).join(' ') : '
No PMID
'; var elTag = function(v) { return '
' + (v || 'unknown') + '
'; }; var causalTag = function(v) { return '
' + (v || 'unknown') + '
'; }; var polTag = function(v) { var cls = (v === '+') ? 'pol-pos' : (v === '-' ? 'pol-neg' : 'pol-neutral'); return '
' + (v || '~') + '
'; }; var html = ''; html += '
'; html += '
'; html += '
' + escHtml(src) + '
'; html += '
→
'; html += '
' + escHtml(tgt) + '
'; html += '
Relation:
' + escHtml(edge.relation || 'N/A') + '
'; html += '
'; html += '
'; html += '
Evidence Level
' + elTag(edge.evidence_level) + '
'; html += '
Causal Strength
' + causalTag(edge.causal_strength) + '
'; html += '
Study Type
' + (edge.study_type || 'unknown') + '
'; html += '
Polarity
' + polTag(edge.polarity) + '
'; html += '
RoB
' + escHtml(edge.risk_of_bias || 'not_assessed') + '
'; html += '
'; html += '
'; html += '
PMID Count
' + (edge.pmid_count_actual || pmids.length || 0) + '
'; html += '
Chain Level
' + (edge.chain_level_src || '?') + ' → ' + (edge.chain_level_tgt || '?') + '
'; html += '
Confidence
' + escHtml(edge.confidence || 'unknown') + '
'; html += '
'; html += '
'; html += '
Evidence Text
'; html += '
' + escHtml(edge.evidence || '(no evidence)') + '
'; html += '
'; html += '
'; html += '
Associated PMIDs (' + pmids.length + ')
'; html += '
' + pmidLinks + '
'; html += '
'; if (edge.conflicts && edge.conflicts.length) { html += '
'; html += '
'; html += '
Conflict Records
'; edge.conflicts.forEach(function(c) { html += '
' + escHtml(c.conflict_reason || 'direction conflict') + ': ' + escHtml(c.pmid_main || '') + (c.pmid_other ? ' vs ' + c.pmid_other : '') + '
'; }); html += '
'; } if (edges.length > 1) { html += '
'; html += '
Other ' + (edges.length - 1) + ' Related Edges
'; edges.slice(1).forEach(function(e) { html += '
'; html += '
' + (e.evidence_level || '?') + '
'; html += '
' + escHtml(e.relation || 'N/A') + '
(PMID: ' + (e.pmid || 'N/A') + ')'; html += ' — ' + escHtml((e.evidence || '').substring(0, 80)); html += '
'; }); html += '
'; } body.innerHTML = html; _currentModalEdge.data = edge; } function closeEdgeModal() { var modal = document.getElementById('edgeDetailModal'); if (modal) modal.classList.add('hidden'); _currentModalEdge = null; } function modalSaveThisPath() { if (!_currentModalEdge) return; var dis = document.getElementById('disease'); savePath(_currentModalEdge.source, _currentModalEdge.target, (dis && dis.value) || '', _currentModalEdge.data); closeEdgeModal(); } // ===== F: 保存路径 ===== var SAVED_PATHS_KEY = 'kg_flipped_class_paths'; function getSavedPaths() { try { return JSON.parse(localStorage.getItem(SAVED_PATHS_KEY) || '[]'); } catch(e) { return []; } } function savePath(source, target, disease, extraData) { var paths = getSavedPaths(); var entry = { id: Date.now(), source: source, target: target, disease: disease || '', chain: (extraData && extraData.chain_level_src ? extraData.chain_level_src + '->' + extraData.chain_level_tgt : ''), polarity: extraData && extraData.polarity, relation: extraData && extraData.relation, evidence_level: extraData && extraData.evidence_level, causal_strength: extraData && extraData.causal_strength, study_type: extraData && extraData.study_type, pmid: extraData && extraData.pmid, evidence: extraData && extraData.evidence, saved_at: new Date().toLocaleString('zh-CN'), }; for (var i = 0; i < paths.length; i++) { if (paths[i].source === entry.source && paths[i].target === entry.target) { paths.splice(i, 1); break; } } paths.unshift(entry); if (paths.length > 50) paths.splice(50); localStorage.setItem(SAVED_PATHS_KEY, JSON.stringify(paths)); renderSavedPaths(); showToast('Path saved: ' + source + ' -> ' + target, 1500); } function renderSavedPaths() { var list = document.getElementById('savedPathsList'); var countEl = document.getElementById('savedCount'); var paths = getSavedPaths(); if (countEl) countEl.textContent = paths.length; if (!list) return; if (!paths.length) { list.innerHTML = '
No saved paths yet
Click table row, then Save
'; return; } list.innerHTML = paths.map(function(p) { var evBadge = p.evidence_level ? '
' + p.evidence_level + '
' : ''; var causalBadge = p.causal_strength ? '
' + p.causal_strength + '
' : ''; return '
' + '
' + escHtml(p.source) + ' → ' + escHtml(p.target) + '
' + '
' + (p.disease ? '
' + escHtml(p.disease) + '
' : '') + (p.chain ? '
' + escHtml(p.chain) + '
' : '') + (p.pmid ? '
PMID:' + escHtml(p.pmid) + '
' : '') + evBadge + causalBadge + '
' + '
' + '
' + (p.saved_at || '') + '
' + '
del
' + '
'; }).join(''); } function deletePath(id) { var paths = getSavedPaths().filter(function(p) { return p.id !== id; }); localStorage.setItem(SAVED_PATHS_KEY, JSON.stringify(paths)); renderSavedPaths(); showToast('Deleted', 1200); } function clearAllPaths() { if (!confirm('Clear all saved paths?')) return; localStorage.setItem(SAVED_PATHS_KEY, '[]'); renderSavedPaths(); showToast('Cleared', 1200); } function toggleSavedPaths() { var panel = document.getElementById('savedPathsPanel'); if (panel) panel.classList.toggle('hidden'); } function exportSankeyPNG() { if (!charts.sankey) { showToast('Sankey not loaded', 1500); return; } try { var url = charts.sankey.getDataURL({ type: 'png', pixelRatio: 2, backgroundColor: '#0a0e1a' }); var a = document.createElement('a'); a.href = url; a.download = 'kg9_sankey_' + new Date().toISOString().slice(0, 19).replace(/:/g, '-') + '.png'; a.click(); showToast('PNG exported', 1500); } catch(e) { showToast('Export failed: ' + e.message, 2000); } } function exportEdgesJSON() { var q = getQuery(); var params = new URLSearchParams(q.replace('?', '')); params.set('limit', '200'); jget('/ai/api/kg/9dim/top_edges?' + params.toString()).then(function(top) { var data = { exported_at: new Date().toISOString(), disease: (document.getElementById('disease') && document.getElementById('disease').value) || 'all', filters: { study_type: (document.getElementById('studyType') && document.getElementById('studyType').value) || '', evidence_level: (document.getElementById('evidenceLevel') && document.getElementById('evidenceLevel').value) || '', }, edges: (top.edges || []).map(function(e) { return { source: e.source, target: e.target, relation: e.relation, polarity: e.polarity, evidence_level: e.evidence_level, causal_strength: e.causal_strength, study_type: e.study_type, pmid_count: e.pc, pmid: e.pmid, evidence_short: e.evidence_short, chain_level_src: e.chain_level_src, chain_level_tgt: e.chain_level_tgt, }; }), saved_paths: getSavedPaths(), }; var blob = new Blob([JSON.stringify(data, null, 2)], {type: 'application/json'}); var url = URL.createObjectURL(blob); var a = document.createElement('a'); a.href = url; a.download = 'kg9_edges_' + new Date().toISOString().slice(0, 19).replace(/:/g, '-') + '.json'; a.click(); URL.revokeObjectURL(url); showToast('JSON exported (' + (top.edges || []).length + ' edges)', 1500); }).catch(function(e) { showToast('Export failed: ' + e.message, 2000); }); } // ===== Toast ===== var _toastTimer = null; function showToast(msg, duration) { var toast = document.getElementById('toastMsg'); if (!toast) { toast = document.createElement('div'); toast.id = 'toastMsg'; toast.style.cssText = 'position:fixed;bottom:20px;left:50%;transform:translateX(-50%);z-index:999999;' + 'background:#1f2937;border:1px solid #3b82f6;color:#e2e8f0;padding:10px 20px;' + 'border-radius:8px;font-size:13px;font-weight:600;box-shadow:0 4px 16px rgba(0,0,0,.5);' + 'transition:opacity .3s;pointer-events:none;white-space:nowrap;'; document.body.appendChild(toast); } toast.textContent = msg; toast.style.opacity = '1'; clearTimeout(_toastTimer); _toastTimer = setTimeout(function() { toast.style.opacity = '0'; }, duration || 2000); } // ===== Patched renderTopEdges ===== var _orig_renderTopEdges = renderTopEdges; function renderTopEdges(top) { var tbody = document.getElementById('topBody'); if (!top.edges || !top.edges.length) { tbody.innerHTML = '
No data
'; return; } tbody.innerHTML = top.edges.map(function(e) { var src = (e.source || '').replace(/'/g, "\'"); var tgt = (e.target || '').replace(/'/g, "\'"); return '
' + '
' + evLevelTag(e.evidence_level) + '
' + '
' + causalTag(e.causal_strength) + '
' + '
' + studyTag(e.study_type) + '
' + '
' + (e.relation || '
-
') + '
' + '
' + polTag(e.polarity) + '
' + '
' + escHtml(e.source || '?') + '
→
' + escHtml(e.target || '?') + '
' + '
' + (e.chain_level_src || '?') + ' → ' + (e.chain_level_tgt || '?') + '
' + '
' + fmt(e.pc || 0) + '
' + '
' + escHtml(e.evidence_short || '') + '
' + '
'; }).join(''); } // ===== Init =====