|
|
@@ -315,14 +315,7 @@ HTML_TEMPLATE = '''<!DOCTYPE html>
|
|
|
stroke: #fff;
|
|
|
stroke-width: 4px;
|
|
|
}}
|
|
|
- .node .post-node {{
|
|
|
- stroke: #fff;
|
|
|
- stroke-dasharray: 4,2;
|
|
|
- }}
|
|
|
- .node .post-node.unmatched {{
|
|
|
- stroke: #555;
|
|
|
- stroke-dasharray: 2,2;
|
|
|
- }}
|
|
|
+ .node .post-node,
|
|
|
.node .persona-node {{
|
|
|
stroke: #fff;
|
|
|
}}
|
|
|
@@ -361,8 +354,7 @@ HTML_TEMPLATE = '''<!DOCTYPE html>
|
|
|
stroke: #2ecc71;
|
|
|
}}
|
|
|
.link.category-intra {{
|
|
|
- stroke: #27ae60;
|
|
|
- stroke-dasharray: 3,3;
|
|
|
+ stroke: #3498db;
|
|
|
}}
|
|
|
.link.tag-cooccur {{
|
|
|
stroke: #f39c12;
|
|
|
@@ -379,7 +371,7 @@ HTML_TEMPLATE = '''<!DOCTYPE html>
|
|
|
stroke: #2ecc71;
|
|
|
}}
|
|
|
.link.mirror-category-intra {{
|
|
|
- stroke: #27ae60;
|
|
|
+ stroke: #3498db;
|
|
|
}}
|
|
|
.link.mirror-tag-cooccur {{
|
|
|
stroke: #f39c12;
|
|
|
@@ -427,13 +419,12 @@ HTML_TEMPLATE = '''<!DOCTYPE html>
|
|
|
display: none;
|
|
|
}}
|
|
|
.controls {{
|
|
|
- position: absolute;
|
|
|
- top: 20px;
|
|
|
- left: 20px;
|
|
|
- background: rgba(22, 33, 62, 0.9);
|
|
|
- padding: 15px;
|
|
|
+ background: rgba(15, 52, 96, 0.5);
|
|
|
+ padding: 12px;
|
|
|
border-radius: 8px;
|
|
|
- z-index: 100;
|
|
|
+ margin-top: auto;
|
|
|
+ border-top: 1px solid #0f3460;
|
|
|
+ padding-top: 15px;
|
|
|
}}
|
|
|
.controls button {{
|
|
|
background: #0f3460;
|
|
|
@@ -500,22 +491,6 @@ HTML_TEMPLATE = '''<!DOCTYPE html>
|
|
|
</div>
|
|
|
<div class="main-content">
|
|
|
<div id="graph">
|
|
|
- <div class="controls">
|
|
|
- <button onclick="resetZoom()">重置视图</button>
|
|
|
- <button onclick="toggleLabels()">切换标签</button>
|
|
|
- <button onclick="toggleCrossLayerEdges()" id="crossLayerBtn">显示跨层边</button>
|
|
|
- <div class="control-group">
|
|
|
- <div class="control-label">人设树配置</div>
|
|
|
- <button onclick="toggleTreeTags()" id="treeTagBtn" class="active">显示标签</button>
|
|
|
- <select id="treeDepthSelect" onchange="setTreeDepth(this.value)">
|
|
|
- <option value="0">全部层级</option>
|
|
|
- <option value="2">2层</option>
|
|
|
- <option value="3">3层</option>
|
|
|
- <option value="4">4层</option>
|
|
|
- <option value="5">5层</option>
|
|
|
- </select>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
<div class="tooltip" id="tooltip"></div>
|
|
|
</div>
|
|
|
<div id="sidebar">
|
|
|
@@ -532,94 +507,58 @@ HTML_TEMPLATE = '''<!DOCTYPE html>
|
|
|
<h2>节点</h2>
|
|
|
<div class="legend-grid">
|
|
|
<div class="legend-item">
|
|
|
- <div class="legend-color" style="background: #666; border: 2px dashed #fff;"></div>
|
|
|
- <span>帖子(虚线)</span>
|
|
|
- </div>
|
|
|
- <div class="legend-item">
|
|
|
- <div class="legend-color" style="background: #666; border: 2px solid #fff;"></div>
|
|
|
- <span>人设(实线)</span>
|
|
|
- </div>
|
|
|
- <div class="legend-item">
|
|
|
- <div class="legend-color" style="background: #666; border-radius: 50%;"></div>
|
|
|
- <span>标签(圆)</span>
|
|
|
- </div>
|
|
|
- <div class="legend-item">
|
|
|
- <div class="legend-color" style="background: #666; border-radius: 2px;"></div>
|
|
|
- <span>分类(方)</span>
|
|
|
- </div>
|
|
|
- <div class="legend-item">
|
|
|
- <div class="legend-color" style="background: #666; opacity: 1;"></div>
|
|
|
- <span>直接匹配</span>
|
|
|
- </div>
|
|
|
- <div class="legend-item">
|
|
|
- <div class="legend-color" style="background: #666; opacity: 0.5;"></div>
|
|
|
- <span>扩展节点</span>
|
|
|
- </div>
|
|
|
- <div class="legend-item">
|
|
|
- <div class="legend-color" style="background: #f39c12;"></div>
|
|
|
+ <div class="legend-color" style="background: #f39c12; border: 2px solid #fff;"></div>
|
|
|
<span>灵感点</span>
|
|
|
</div>
|
|
|
<div class="legend-item">
|
|
|
- <div class="legend-color" style="background: #3498db;"></div>
|
|
|
+ <div class="legend-color" style="background: #3498db; border: 2px solid #fff;"></div>
|
|
|
<span>目的点</span>
|
|
|
</div>
|
|
|
<div class="legend-item">
|
|
|
- <div class="legend-color" style="background: #9b59b6;"></div>
|
|
|
+ <div class="legend-color" style="background: #9b59b6; border: 2px solid #fff;"></div>
|
|
|
<span>关键点</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <h2>边(人设/实线)</h2>
|
|
|
+ <h2>边</h2>
|
|
|
<div class="legend-grid">
|
|
|
<div class="legend-item">
|
|
|
<div class="legend-line" style="background: #e94560;"></div>
|
|
|
<span>匹配</span>
|
|
|
</div>
|
|
|
- <div class="legend-item">
|
|
|
- <div class="legend-line" style="background: #2ecc71;"></div>
|
|
|
- <span>分类共现(跨)</span>
|
|
|
- </div>
|
|
|
- <div class="legend-item">
|
|
|
- <div class="legend-line" style="background: #27ae60;"></div>
|
|
|
- <span>分类共现(内)</span>
|
|
|
- </div>
|
|
|
- <div class="legend-item">
|
|
|
- <div class="legend-line" style="background: #f39c12;"></div>
|
|
|
- <span>标签共现</span>
|
|
|
- </div>
|
|
|
<div class="legend-item">
|
|
|
<div class="legend-line" style="background: #9b59b6;"></div>
|
|
|
<span>属于</span>
|
|
|
</div>
|
|
|
<div class="legend-item">
|
|
|
- <div class="legend-line" style="background: #8e44ad;"></div>
|
|
|
- <span>包含</span>
|
|
|
+ <div class="legend-line" style="background: #2ecc71;"></div>
|
|
|
+ <span>分类共现(跨)</span>
|
|
|
</div>
|
|
|
- </div>
|
|
|
- <h2>帖子镜像边(直接)</h2>
|
|
|
- <div class="legend-grid">
|
|
|
<div class="legend-item">
|
|
|
- <div class="legend-line" style="background: #2ecc71;"></div>
|
|
|
- <span>分类共现</span>
|
|
|
+ <div class="legend-line" style="background: #3498db;"></div>
|
|
|
+ <span>分类共现(内)</span>
|
|
|
</div>
|
|
|
<div class="legend-item">
|
|
|
<div class="legend-line" style="background: #f39c12;"></div>
|
|
|
<span>标签共现</span>
|
|
|
</div>
|
|
|
- <div class="legend-item">
|
|
|
- <div class="legend-line" style="background: #9b59b6;"></div>
|
|
|
- <span>属于</span>
|
|
|
- </div>
|
|
|
- <div class="legend-item">
|
|
|
- <div class="legend-line" style="background: #8e44ad;"></div>
|
|
|
- <span>包含</span>
|
|
|
- </div>
|
|
|
</div>
|
|
|
- <h2>帖子镜像边(二阶)</h2>
|
|
|
- <div class="legend-grid">
|
|
|
- <div class="legend-item">
|
|
|
- <div class="legend-line" style="background: repeating-linear-gradient(90deg, #17a2b8, #17a2b8 8px, transparent 8px, transparent 11px, #17a2b8 11px, #17a2b8 13px, transparent 13px, transparent 16px);"></div>
|
|
|
- <span>通过扩展节点</span>
|
|
|
- </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="controls">
|
|
|
+ <div class="control-label">视图控制</div>
|
|
|
+ <button onclick="resetZoom()">重置视图</button>
|
|
|
+ <button onclick="toggleLabels()">切换标签</button>
|
|
|
+ <button onclick="toggleCrossLayerEdges()" id="crossLayerBtn">显示跨层边</button>
|
|
|
+ <div class="control-group">
|
|
|
+ <div class="control-label">人设树配置</div>
|
|
|
+ <button onclick="toggleTreeTags()" id="treeTagBtn" class="active">显示标签</button>
|
|
|
+ <select id="treeDepthSelect" onchange="setTreeDepth(this.value)">
|
|
|
+ <option value="0">全部层级</option>
|
|
|
+ <option value="2">2层</option>
|
|
|
+ <option value="3">3层</option>
|
|
|
+ <option value="4">4层</option>
|
|
|
+ <option value="5">5层</option>
|
|
|
+ </select>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -1429,8 +1368,8 @@ HTML_TEMPLATE = '''<!DOCTYPE html>
|
|
|
"分类层级": "#2ecc71", // 绿色 - 分类的层级关系
|
|
|
"属于": "#9b59b6", // 紫色 - 标签属于分类
|
|
|
"包含": "#8e44ad", // 深紫 - 分类包含标签
|
|
|
- "分类共现(跨点)": "#e74c3c", // 红色 - 跨维度分类共现
|
|
|
- "分类共现(点内)": "#c0392b", // 深红 - 同维度分类共现
|
|
|
+ "分类共现(跨点)": "#2ecc71", // 绿色 - 跨帖子分类共现
|
|
|
+ "分类共现(点内)": "#3498db", // 蓝色 - 同帖子分类共现
|
|
|
"标签共现": "#f39c12" // 橙色 - 标签共现
|
|
|
}};
|
|
|
const treeEdgeDash = {{
|
|
|
@@ -1675,32 +1614,29 @@ HTML_TEMPLATE = '''<!DOCTYPE html>
|
|
|
.on("end", dragended));
|
|
|
|
|
|
// 根据节点类型绘制不同形状
|
|
|
- // - 点节点(帖子点):六边形(更大)
|
|
|
+ // - 点节点(帖子点):六边形
|
|
|
// - 标签节点:圆形
|
|
|
// - 分类节点:方形
|
|
|
+ // 帖子标签用虚线,人设标签用实线
|
|
|
node.each(function(d) {{
|
|
|
const el = d3.select(this);
|
|
|
- const isExpanded = d.是否扩展 === true;
|
|
|
- const isUnmatched = d.source === "帖子" && d.节点类型 === "标签" && d.已匹配 === false;
|
|
|
const isPointNode = d.节点类型 === "点";
|
|
|
+ const isPostNode = d.source === "帖子";
|
|
|
|
|
|
- // 点节点更大,标签节点根据来源区分大小
|
|
|
+ // 节点大小
|
|
|
let size;
|
|
|
if (isPointNode) {{
|
|
|
size = 16; // 点节点最大
|
|
|
- }} else if (d.source === "帖子") {{
|
|
|
+ }} else if (isPostNode) {{
|
|
|
size = 12; // 帖子标签
|
|
|
- }} else if (isExpanded) {{
|
|
|
- size = 8; // 扩展的分类节点
|
|
|
}} else {{
|
|
|
size = 10; // 人设标签
|
|
|
}}
|
|
|
|
|
|
const fill = levelColors[d.level] || "#666";
|
|
|
- const nodeClass = d.source === "帖子"
|
|
|
- ? (isPointNode ? "post-point-node" : (isUnmatched ? "post-node unmatched" : "post-node"))
|
|
|
+ const nodeClass = isPostNode
|
|
|
+ ? (isPointNode ? "post-point-node" : "post-node")
|
|
|
: "persona-node";
|
|
|
- const opacity = isExpanded ? 0.5 : (isUnmatched ? 0.4 : 1);
|
|
|
|
|
|
if (isPointNode) {{
|
|
|
// 六边形(点节点)
|
|
|
@@ -1712,8 +1648,7 @@ HTML_TEMPLATE = '''<!DOCTYPE html>
|
|
|
el.append("polygon")
|
|
|
.attr("points", hexPoints.map(p => p.join(",")).join(" "))
|
|
|
.attr("fill", fill)
|
|
|
- .attr("class", nodeClass)
|
|
|
- .attr("opacity", opacity);
|
|
|
+ .attr("class", nodeClass);
|
|
|
}} else if (d.节点类型 === "分类") {{
|
|
|
// 方形(分类节点)
|
|
|
el.append("rect")
|
|
|
@@ -1723,15 +1658,13 @@ HTML_TEMPLATE = '''<!DOCTYPE html>
|
|
|
.attr("y", -size)
|
|
|
.attr("fill", fill)
|
|
|
.attr("class", nodeClass)
|
|
|
- .attr("rx", 3)
|
|
|
- .attr("opacity", opacity);
|
|
|
+ .attr("rx", 3);
|
|
|
}} else {{
|
|
|
// 圆形(标签节点)
|
|
|
el.append("circle")
|
|
|
.attr("r", size)
|
|
|
- .attr("fill", isUnmatched ? "#666" : fill)
|
|
|
- .attr("class", nodeClass)
|
|
|
- .attr("opacity", opacity);
|
|
|
+ .attr("fill", fill)
|
|
|
+ .attr("class", nodeClass);
|
|
|
}}
|
|
|
}});
|
|
|
|
|
|
@@ -2487,7 +2420,7 @@ HTML_TEMPLATE = '''<!DOCTYPE html>
|
|
|
const edgeColors = {{
|
|
|
"属于": "#9b59b6", // 紫色 - 层级关系
|
|
|
"分类共现(跨点)": "#2ecc71", // 绿色 - 跨帖子分类共现
|
|
|
- "分类共现(点内)": "#27ae60", // 深绿 - 同帖子分类共现
|
|
|
+ "分类共现(点内)": "#3498db", // 蓝色 - 同帖子分类共现
|
|
|
"标签共现": "#f39c12" // 橙色 - 标签共现
|
|
|
}};
|
|
|
|
|
|
@@ -2665,7 +2598,7 @@ HTML_TEMPLATE = '''<!DOCTYPE html>
|
|
|
const edgeColors = {{
|
|
|
"属于": "#9b59b6",
|
|
|
"分类共现(跨点)": "#2ecc71",
|
|
|
- "分类共现(点内)": "#27ae60",
|
|
|
+ "分类共现(点内)": "#3498db",
|
|
|
"标签共现": "#f39c12"
|
|
|
}};
|
|
|
|