刘立冬 3 veckor sedan
förälder
incheckning
472ddbfbeb

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 21668 - 0
visualization.html


+ 11 - 1
visualization/sug_v6_1_2_121/convert_v8_to_graph_v3.js

@@ -338,6 +338,11 @@ function convertV8ToGraphV2(runContext, searchResults) {
         domainCombinations.forEach((comb, combIndex) => {
           const combId = `comb_${comb.text}_r${roundNum}_${combIndex}`;
           const domainsStr = comb.domains ? comb.domains.map(d => `D${d}`).join(',') : '';
+          const wordDetails = comb.source_word_details || [];
+          const isAboveSources = comb.is_above_source_scores || false;
+          const scoreColor = wordDetails.length > 0
+            ? (isAboveSources ? '#22c55e' : '#ef4444')
+            : null;
 
           nodes[combId] = {
             type: 'domain_combination',
@@ -352,7 +357,12 @@ function convertV8ToGraphV2(runContext, searchResults) {
             source_words: comb.source_words || [],
             from_segments: comb.from_segments || [],
             domains: comb.domains || [],
-            domains_str: domainsStr
+            domains_str: domainsStr,
+            source_word_details: wordDetails,
+            source_scores: comb.source_scores || [],
+            is_above_sources: isAboveSources,
+            max_source_score: comb.max_source_score ?? null,
+            scoreColor: scoreColor
           };
 
           edges.push({

+ 87 - 0
visualization/sug_v6_1_2_121/index.js

@@ -353,6 +353,37 @@ function QueryNode({ id, data, sourcePosition, targetPosition }) {
                 <strong>Parent:</strong> {data.parent}
               </div>
             )}
+            {data.nodeType === 'domain_combination' && Array.isArray(data.source_word_details) && data.source_word_details.length > 0 && (
+              <div style={{
+                marginTop: '6px',
+                paddingTop: '6px',
+                borderTop: '1px solid #f3f4f6',
+                fontSize: '10px',
+                color: '#6b7280',
+                lineHeight: '1.5',
+              }}>
+                <strong style={{ color: '#4b5563' }}>来源词得分:</strong>
+                <div style={{ marginTop: '4px', display: 'flex', flexDirection: 'column', gap: '4px' }}>
+                  {data.source_word_details.map((detail, idx) => {
+                    const words = (detail.words || []).map((w) => {
+                      const numericScore = typeof w.score === 'number' ? w.score : parseFloat(w.score || '0');
+                      const formattedScore = Number.isFinite(numericScore) ? numericScore.toFixed(2) : '0.00';
+                      return w.text + ' (' + formattedScore + ')';
+                    }).join(' + ');
+                    const segmentLabel = detail.segment_type ? '[' + detail.segment_type + '] ' : '';
+                    return (
+                      <div key={idx} style={{ display: 'flex', flexWrap: 'wrap', gap: '4px', alignItems: 'center' }}>
+                        {segmentLabel && <span style={{ color: '#4b5563' }}>{segmentLabel}</span>}
+                        <span style={{ color: '#2563eb' }}>{words}</span>
+                      </div>
+                    );
+                  })}
+                </div>
+                <div style={{ marginTop: '4px', fontWeight: '500', color: data.is_above_sources ? '#16a34a' : '#dc2626' }}>
+                  {data.is_above_sources ? '✅ 组合得分高于所有来源词' : '⚠️ 组合得分未超过全部来源词'}
+                </div>
+              </div>
+            )}
             {data.selectedWord && (
               <div style={{
                 marginTop: '6px',
@@ -794,6 +825,26 @@ function TreeNode({ node, level, children, isCollapsed, onToggle, isSelected, on
   const strategy = getPrimaryStrategy(node.data);  // 使用智能提取函数
   const strategyColor = getStrategyColor(strategy);
   const nodeActualType = node.data.nodeType || node.type; // 获取实际节点类型
+  const isDomainCombination = nodeActualType === 'domain_combination';
+
+  let sourceSummary = '';
+  if (isDomainCombination && Array.isArray(node.data.source_word_details) && node.data.source_word_details.length > 0) {
+    const summaryParts = [];
+    node.data.source_word_details.forEach((detail) => {
+      const words = Array.isArray(detail.words) ? detail.words : [];
+      const wordTexts = [];
+      words.forEach((w) => {
+        const numericScore = typeof w.score === 'number' ? w.score : parseFloat(w.score || '0');
+        const formattedScore = Number.isFinite(numericScore) ? numericScore.toFixed(2) : '0.00';
+        wordTexts.push(w.text + ' (' + formattedScore + ')');
+      });
+      if (wordTexts.length > 0) {
+        const segmentLabel = detail.segment_type ? '[' + detail.segment_type + '] ' : '';
+        summaryParts.push(segmentLabel + wordTexts.join(' + '));
+      }
+    });
+    sourceSummary = summaryParts.join(' | ');
+  }
 
   // 计算字体颜色:根据分数提升幅度判断
   let fontColor = '#374151'; // 默认颜色
@@ -950,6 +1001,38 @@ function TreeNode({ node, level, children, isCollapsed, onToggle, isSelected, on
             )}
           </div>
 
+          {/* 域组合的来源词得分(树状视图,右对齐) */}
+          {isDomainCombination && sourceSummary && (
+            <div style={{
+              fontSize: '10px',
+              color: '#2563eb',
+              lineHeight: '1.4',
+              display: 'flex',
+              flexDirection: 'column',
+              alignItems: 'flex-end',
+              gap: '2px',
+              textAlign: 'right',
+            }}>
+              {node.data.source_word_details.map((detail, idx) => {
+                const summary = (() => {
+                  const words = Array.isArray(detail.words) ? detail.words : [];
+                  const parts = words.map((w) => {
+                    const numericScore = typeof w.score === 'number' ? w.score : parseFloat(w.score || '0');
+                    const formattedScore = Number.isFinite(numericScore) ? numericScore.toFixed(2) : '0.00';
+                    return w.text + ' (' + formattedScore + ')';
+                  });
+                  const prefix = detail.segment_type ? '[' + detail.segment_type + '] ' : '';
+                  return prefix + parts.join(' + ');
+                })();
+                return (
+                  <span key={idx} title={summary}>
+                    {summary}
+                  </span>
+                );
+              })}
+            </div>
+          )}
+
           {/* 分数下划线 - 步骤和轮次节点不显示 */}
           {nodeActualType !== 'step' && nodeActualType !== 'round' && (
             <div style={{
@@ -1158,6 +1241,10 @@ function transformData(data) {
             domains: node.domains || [], // 域索引数组(domain_combination节点特有)
             domains_str: node.domains_str || '', // 域标识字符串(如"D0,D1")
             from_segments: node.from_segments || [], // 来源segments(domain_combination节点特有)
+            source_word_details: node.source_word_details || [], // 组合来源词及其得分
+            source_scores: node.source_scores || [], // 扁平来源得分
+            is_above_sources: node.is_above_sources || false, // 组合是否高于来源得分
+            max_source_score: node.max_source_score !== undefined ? node.max_source_score : null, // 来源最高分
           },
           position: { x: 0, y: 0 },
         });

Vissa filer visades inte eftersom för många filer har ändrats